import pandas as pd
import numpy as np
import json
import copy
import datetime
from mapping import mapping
from area import Area
from sklearn.preprocessing import StandardScaler
from sklearn.manifold import TSNE


areas, sensor2pos, sensor2area, pos2sensor = mapping()

days = [pd.read_csv(f'../../dataset/org/log/day{d}.csv', sep=',').to_numpy() for d in range(1,4)]


def singleDay(day):
    people_area_time = {}

    for step, _ in enumerate(day):
        time = day[step][2]
        uid = day[step][0]
        sid = day[step][1]
        area = sensor2area[sid]

        if people_area_time.get(uid) is None:
            people_area_time[uid] = {}
            people_area_time[uid]['last_area'] = None
            people_area_time[uid]['area'] = {}
        if people_area_time[uid]['area'].get(area) is None:
            people_area_time[uid]['area'][area] = { 'last_time': time, 'duration' : 0 }

        last_area = people_area_time[uid]['last_area']

        if last_area is not None:
            people_area_time[uid]['area'][last_area]['duration'] += time - people_area_time[uid]['area'][last_area]['last_time']
            people_area_time[uid]['area'][last_area]['last_time'] = time

        people_area_time[uid]['last_area'] = area
        people_area_time[uid]['area'][area]['last_time'] = time

    return people_area_time



for di, day in enumerate(days):
    points = {}

    people_area_time = singleDay(day=day)

    for uid in people_area_time:
        point = []
        
        area_time = people_area_time[uid]['area'].get("main_venue")
        if area_time is not None: point.append(area_time['duration'])
        else: point.append(0.0)
        
        area_time = people_area_time[uid]['area'].get("sub_venue_A")
        if area_time is not None: point.append(area_time['duration'])
        else: point.append(0.0)
        
        area_time = people_area_time[uid]['area'].get("sub_venue_B")
        if area_time is not None: point.append(area_time['duration'])
        else: point.append(0.0)
        
        area_time = people_area_time[uid]['area'].get("sub_venue_C")
        if area_time is not None: point.append(area_time['duration'])
        else: point.append(0.0)
        
        area_time = people_area_time[uid]['area'].get("sub_venue_D")
        if area_time is not None: point.append(area_time['duration'])
        else: point.append(0.0)
        
        area_time = people_area_time[uid]['area'].get("diningroom")
        if area_time is not None: point.append(area_time['duration'])
        else: point.append(0.0)
        
        toilet_time=0.0
        area_time = people_area_time[uid]['area'].get("toilet1")
        if area_time is not None: toilet_time += area_time['duration']
        area_time = people_area_time[uid]['area'].get("toilet2")
        if area_time is not None: toilet_time += area_time['duration']
        area_time = people_area_time[uid]['area'].get("toilet3")
        if area_time is not None: toilet_time += area_time['duration']
        point.append(toilet_time)

        reg_time = people_area_time[uid]['area'].get('register')
        if reg_time is not None and reg_time['duration'] > 0.0:
            point.append(1.0)
        else:
            point.append(0.0)

        if points.get(uid) is None: points[uid] = np.array(point) 
        else: points[uid] += np.array(point) 

    points_l = np.array([points[uid] for uid in points])

    scaled_data = StandardScaler().fit_transform(points_l)
    reduced_data = TSNE(perplexity=30).fit_transform(scaled_data)

    output_data = []

    for i,uid in enumerate(points):
        output_data.append( {
            'id':           int(uid),
            'x':            float(reduced_data[i][0]),
            'y':            float(reduced_data[i][1]),
            'main_venue':   float(points[uid][0]),
            'sub_venue_A':  float(points[uid][1]),
            'sub_venue_B':  float(points[uid][2]),
            'sub_venue_C':  float(points[uid][3]),
            'sub_venue_D':  float(points[uid][4]),
            'diningroom':  float(points[uid][5]),
            'toilet':        float(points[uid][6]),
            'is_registered':   bool(points[uid][7]),
        })


    json_str = json.dumps(output_data)
    with open(f'../../dataset/prcd/reduced_day{di+1}.json', 'w') as fout:
        print(f'output: {fout.name}')
        fout.write(json_str)
        fout.flush()


# import matplotlib.pyplot as plt
# plt.scatter(
#     reduced_data[:,0],
#     reduced_data[:,1],
#     s=2
# )
# plt.show()
